﻿using Coater.Enum;
using Coater.Helper;
using System;
using System.Data;
using System.IO;
using System.Windows.Forms;

namespace Coater
{
    public partial class FormRecipe : Form
    {
        private string FileName { get; set; }
        private bool IsChanged { get; set; } = false;

        public FormRecipe()
        {
            InitializeComponent();
        }

        private void BindData()
        {
            List<ComboBox> li = new List<ComboBox>();
            ComFunc.GetControl(this, ref li);
            foreach (var con in li)
            {
                if (con.Name.StartsWith("cmbNozzle_")
                 || con.Name.StartsWith("cmbSecNozzle_"))
                {
                    BindCmbNozzle(con);
                }
            }
        }

        private void FormRecipe_Load(object sender, EventArgs e)
        {
            BindData();
            LoadRecipe(null);
        }

        private void chk_CheckedChanged(object sender, EventArgs e)
        {
            IsChanged = true;
            CheckBox chk = (CheckBox)sender;
            var conRPMs = Controls.Find($"numRPM_{chk.Tag}", true);
            if (conRPMs.Length > 0)
            {
                conRPMs[0].Enabled = chk.Checked;
            }
            var conAccels = Controls.Find($"numAccel_{chk.Tag}", true);
            if (conAccels.Length > 0)
            {
                conAccels[0].Enabled = chk.Checked;
            }
            var conNozzles = Controls.Find($"cmbNozzle_{chk.Tag}", true);
            if (conNozzles.Length > 0)
            {
                conNozzles[0].Enabled = chk.Checked;
            }
            var conSecNozzles = Controls.Find($"cmbSecNozzle_{chk.Tag}", true);
            if (conSecNozzles.Length > 0)
            {
                conSecNozzles[0].Enabled = chk.Checked;
            }
            var conFroms = Controls.Find($"numFrom_{chk.Tag}", true);
            if (conFroms.Length > 0)
            {
                conFroms[0].Enabled = chk.Checked;
            }
            var conTos = Controls.Find($"numTo_{chk.Tag}", true);
            if (conTos.Length > 0)
            {
                conTos[0].Enabled = chk.Checked;
            }
            var conTimes = Controls.Find($"numTime_{chk.Tag}", true);
            if (conTimes.Length > 0)
            {
                conTimes[0].Enabled = chk.Checked;
            }
        }

        private void LoadRecipe(RecipeInfo? recipe)
        {
            if (recipe == null)
            {
                FileName = string.Empty;
                this.Text = "Recipe-Unnamed";
                this.cmbWaferSize.SelectedIndex = 1;
                this.cmbWaferType.SelectedIndex = 0;
                this.cmbReadyCheck.SelectedIndex = 0;
                this.numDelay.Value = 0;
                this.chkWaferWash.Checked = false;
                this.chkDisableChuck.Checked = false;
                this.chkCloseIO.Checked = false;
                this.txtDesc.Clear();
                for (int i = 1; i < 11; i++)
                {
                    var conChks = Controls.Find($"chk_{i}", true);
                    if (conChks.Length > 0 && conChks[0] is CheckBox chk)
                    {
                        chk.Checked = false;
                    }
                    var conRPMs = Controls.Find($"numRPM_{i}", true);
                    if (conRPMs.Length > 0 && conRPMs[0] is NumericUpDown numRPM)
                    {
                        numRPM.Value = 0;
                    }
                    var conAccels = Controls.Find($"numAccel_{i}", true);
                    if (conAccels.Length > 0 && conAccels[0] is NumericUpDown numAccel)
                    {
                        numAccel.Value = 0;
                    }
                    var conNozzles = Controls.Find($"cmbNozzle_{i}", true);
                    if (conNozzles.Length > 0 && conNozzles[0] is ComboBox numNozzle)
                    {
                        numNozzle.SelectedIndex = 0;
                    }
                    var conSecNozzles = Controls.Find($"cmbSecNozzle_{i}", true);
                    if (conSecNozzles.Length > 0 && conSecNozzles[0] is ComboBox numSecNozzle)
                    {
                        numSecNozzle.SelectedIndex = 0;
                    }
                    var conFroms = Controls.Find($"numFrom_{i}", true);
                    if (conFroms.Length > 0 && conFroms[0] is NumericUpDown numFrom)
                    {
                        numFrom.Value = 0;
                    }
                    var conTos = Controls.Find($"numTo_{i}", true);
                    if (conTos.Length > 0 && conTos[0] is NumericUpDown numTo)
                    {
                        numTo.Value = 0;
                    }
                    var conTimes = Controls.Find($"numTime_{i}", true);
                    if (conTimes.Length > 0 && conTimes[0] is NumericUpDown numTime)
                    {
                        numTime.Value = 0;
                    }
                }
            }
            else
            {
                this.txtDesc.Text = recipe.Description;
                this.cmbWaferSize.Text = recipe.WaferSize;
                this.cmbWaferType.Text = recipe.WaferType;
                this.cmbReadyCheck.Text = recipe.ReadyCheck;
                this.numDelay.Value = recipe.Delay;
                this.chkWaferWash.Checked = recipe.WaferWash;
                this.chkDisableChuck.Checked = recipe.DisableChuck;
                this.chkCloseIO.Checked = recipe.CloseIO;
                foreach (var step in recipe.Steps)
                {
                    var conChks = Controls.Find($"chk_{step.Step}", true);
                    if (conChks.Length > 0 && conChks[0] is CheckBox chk)
                    {
                        chk.Checked = step.Enable;
                    }
                    var conRPMs = Controls.Find($"numRPM_{step.Step}", true);
                    if (conRPMs.Length > 0 && conRPMs[0] is NumericUpDown numRPM)
                    {
                        numRPM.Value = step.SpinRPM;
                    }
                    var conAccels = Controls.Find($"numAccel_{step.Step}", true);
                    if (conAccels.Length > 0 && conAccels[0] is NumericUpDown numAccel)
                    {
                        numAccel.Value = step.SpinAccel;
                    }
                    var conNozzles = Controls.Find($"cmbNozzle_{step.Step}", true);
                    if (conNozzles.Length > 0 && conNozzles[0] is ComboBox numNozzle)
                    {
                        numNozzle.SelectedValue = step.Nozzle;
                    }
                    var conSecNozzles = Controls.Find($"cmbSecNozzle_{step.Step}", true);
                    if (conSecNozzles.Length > 0 && conSecNozzles[0] is ComboBox numSecNozzle)
                    {
                        numSecNozzle.SelectedValue = step.SecondNozzle;
                    }
                    var conFroms = Controls.Find($"numFrom_{step.Step}", true);
                    if (conFroms.Length > 0 && conFroms[0] is NumericUpDown numFrom)
                    {
                        numFrom.Value = step.From;
                    }
                    var conTos = Controls.Find($"numTo_{step.Step}", true);
                    if (conTos.Length > 0 && conTos[0] is NumericUpDown numTo)
                    {
                        numTo.Value = step.To;
                    }
                    var conTimes = Controls.Find($"numTime_{step.Step}", true);
                    if (conTimes.Length > 0 && conTimes[0] is NumericUpDown numTime)
                    {
                        numTime.Value = step.Time;
                    }
                }
                IsChanged = false;
            }
        }

        private RecipeInfo GetCurrentRecipeInfo()
        {
            RecipeInfo recipe = new RecipeInfo();
            recipe.WaferSize = this.cmbWaferSize.Text;
            recipe.WaferType = this.cmbWaferType.Text;
            recipe.ReadyCheck = this.cmbReadyCheck.Text;
            recipe.Delay = (int)this.numDelay.Value;
            recipe.WaferWash = this.chkWaferWash.Checked;
            recipe.DisableChuck = this.chkDisableChuck.Checked;
            recipe.CloseIO = this.chkCloseIO.Checked;
            recipe.Description = this.txtDesc.Text;
            for (int i = 1; i < 11; i++)
            {
                StepInfo step = new StepInfo();
                step.Step = i;
                step.Enable = ((CheckBox)this.Controls.Find($"chk_{i}", true)[0]).Checked;
                step.SpinRPM = (int)((NumericUpDown)this.Controls.Find($"numRPM_{i}", true)[0]).Value;
                step.SpinAccel = (int)((NumericUpDown)this.Controls.Find($"numAccel_{i}", true)[0]).Value;
                step.Nozzle = (NozzleEnum)((ComboBox)this.Controls.Find($"cmbNozzle_{i}", true)[0]).SelectedValue;
                step.SecondNozzle = (NozzleEnum)((ComboBox)this.Controls.Find($"cmbSecNozzle_{i}", true)[0]).SelectedValue;
                step.From = (int)((NumericUpDown)this.Controls.Find($"numFrom_{i}", true)[0]).Value;
                step.To = (int)((NumericUpDown)this.Controls.Find($"numTo_{i}", true)[0]).Value;
                step.Time = (int)((NumericUpDown)this.Controls.Find($"numTime_{i}", true)[0]).Value;
                recipe.Steps.Add(step);
            }
            return recipe;
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (IsChanged)
            {
                if (MessageBox.Show("Changes were detected to the current recipe.\r\nAbandon these changes?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
                {
                    return;
                }
            }
            LoadRecipe(null);
        }

        private void openToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Recipe files (*.xml)|*.xml";
            ofd.Multiselect = false;
            ofd.InitialDirectory = DeviceContext.Instance.Config.RecipePath;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                RecipeInfo recipe = XMLHelper.GetSettings_FullName<RecipeInfo>(ofd.FileName);
                FileName = ofd.FileName;
                this.Text = $"Recipe-{ofd.SafeFileName}";
                LoadRecipe(recipe);
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RecipeInfo recipeInfo = GetCurrentRecipeInfo();
            if (FileName != string.Empty)
            {
                XMLHelper.SaveSettings_FullName(FileName, recipeInfo);
                IsChanged = false;
            }
            else
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = "Recipe files (*.xml)|*.xml";
                saveFileDialog.InitialDirectory = DeviceContext.Instance.Config.RecipePath;
                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    FileName = saveFileDialog.FileName;
                    XMLHelper.SaveSettings_FullName(FileName, recipeInfo);
                    this.Text = $"Recipe-{Path.GetFileName(saveFileDialog.FileName)}";
                    IsChanged = false;
                }
            }
        }

        private void saveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            RecipeInfo recipeInfo = GetCurrentRecipeInfo();
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.Filter = "Recipe files (*.xml)|*.xml";
            saveFileDialog.InitialDirectory = DeviceContext.Instance.Config.RecipePath;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                FileName = saveFileDialog.FileName;
                XMLHelper.SaveSettings_FullName(FileName, recipeInfo);
                this.Text = $"Recipe-{Path.GetFileName(saveFileDialog.FileName)}";
                IsChanged = false;
            }
        }

        private void TextChanged(object sender, EventArgs e)
        {
            IsChanged = true;
        }

        private DataTable dtNozzle()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("key", typeof(string));
            dt.Columns.Add("value", typeof(NozzleEnum));

            DataRow dr0 = dt.NewRow();
            dr0["key"] = "Off";
            dr0["value"] = NozzleEnum.Off;
            dt.Rows.Add(dr0);
            foreach (var nozzle in DeviceContext.Instance.Nozzles)
            {
                if (nozzle.Nozzle != NozzleEnum.Nozzle6
                || (nozzle.Nozzle == NozzleEnum.Nozzle6 && DeviceContext.Instance.Config.Coater.EnableBacksideNozzle6))
                {
                    DataRow dr = dt.NewRow();
                    dr["key"] = nozzle.Nozzle.GetName() + " - " + nozzle.NozzleName;
                    dr["value"] = nozzle.Nozzle;
                    dt.Rows.Add(dr);
                }
            }
            return dt;
        }

        private void BindCmbNozzle(ComboBox cmb)
        {
            cmb.DataSource = dtNozzle();
            cmb.DisplayMember = "key";
            cmb.ValueMember = "value";
        }

        private void FormRecipe_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("Changes were detected to the current recipe.\r\nAbandon these changes?", "Confirm", MessageBoxButtons.YesNo, MessageBoxIcon.Information) == DialogResult.No)
            {
                e.Cancel = true;
            }
        }
    }
}
